【机器学习笔记】:大话线性回归(三)
点击上方 ↑ 蓝色,关注“Python数据科学”
作者 | xiaoyu
知乎 | https://zhuanlan.zhihu.com/pypcfx
介绍 | 一个半路转行的数据挖掘工程师
接着前两篇继续介绍本篇,前两篇链接如下:
本篇介绍线性回归诊断的余下部分:
多重共线性分析
强影响点分析
▌多重共线性检验
1. 多重共线性产生的问题
当回归模型中两个或两个以上的自变量彼此相关时,则称回归模型中存在多重共线性,也就是说共线性的自变量提供了重复的信息。
那么这种多重共线性会有什么不好的影响吗?答案是会的,而且影响非常不好。总结一下就是:会造成回归系数,截距系数的估计非常不稳定,即整个模型是不稳定。这种不稳定的具体表现是:很可能回归系数原来正,但因为共线性而变为负。这对于一些自变量的可解释性来讲可能是致命的,因为得到错误系数无法解释正常发生的现象。
那究竟为什么多重共线性会导致回归系数,以及模型不稳定呢?举个简单的例子说明下:比如我有一个二元线性回归模型,自变量是x1和x2,如果我们画图大家可以很自然的想象出一个三维(三轴)坐标系。假如x1和x2之间没有多重共线性,那么这个模型就是一个确定了的超平面。但假如x1和x2有很强的多重共线性,那么这个模型就近似是一个直线向量,而以这个直线所拟合出来的平面是无数个的(穿过一条直线的平面是不固定的)。这也就造成了回归系数的不确定性,以及模型无法稳定。
2. 多重共线性的检测
多重共线性有很多检测方法,最简单直接的就是计算各自变量之间的相关系数,并进行显著性检验。具体的,如果出现以下情况,可能存在多重共线性:
(1)模型中各对自变量之间显著性相关。
(2)当模型线性关系(F检验)显著时,几乎所有回归系数的t检验不显著。
(3)回归系数的正负号与预期的相反。
(4)方差膨胀因子(VIF)检测,一般认为VIF大于10,则存在严重的多重共线性。
这里主要说明一下(1)和(4),因为(2)和(3)一般通过观察即可。
相关系数检验
相关系数的公式如下,协方差除以各自变量的方差。
由于提供数据集变量不适合相关系数举例,因此为了说明Python中如何使用,采取了随机数的方法。主要是用到了DataFrame的corr()方法,默认皮尔逊相关,然后通过seaborn的heatmap可以可视化展示出来。以下是代码部分:
import seaborn as sns
import numpy as np
import pandas as pd
a = np.random.rand(4,3)
print(pd.DataFrame(np.round(a,2), columns = ['a', 'b', 'c'], index = range(1,5)).corr())
fig, ax = plt.subplots(figsize = (10,10))
sns.heatmap(pd.DataFrame(np.round(a,2),
columns = ['a', 'b', 'c'],
index = range(1,5)),
cmap="YlGnBu")
sns.pairplot(pd.DataFrame(np.round(a,2)))
plt.show()
可以看到:a和b(正相关)相关系数为0.846,有很强的相关系数,存在多重共线性。
方差膨胀因子经验
另一种计算的方法就是通过方差膨胀因子判断。方差膨胀因子的公式如下:
VIF的公式是基于拟合优度R2的,其中VIF代表自变量X的方差膨胀系数,R代表把自变量X最为因变量,与其他自变量做回归时的R2。关于R2介绍可以参考【机器学习笔记】:大话线性回归(二)。具体的代码部分如下:
# 自定义VIF方差膨胀因子计算
import statsmodels.formula.api as smf
def vif(df, col_i):
cols = list(df.columns)
cols.remove(col_i)
cols_noti = cols
formula = col_i + '~' + '+'.join(cols_noti)
r2 = smf.ols(formula, df).fit().rsquared
return 1./(1.-r2)
for i in df.columns:
print(i, '\t', vif(df,col_i=i))
如果自变量X与其他自变量共线性强,那么回归方程的R2就会较高,导致VIF也高。一般,有自变量VIF值大于10,则说明存在严重多重共线性,可以选择删除该变量或者用其他类似但VIF低的变量代替。
3. 多重共线性的处理方法
多重共线性对于线性回归是种灾难,并且我们不可能完全消除,而只能利用一些方法来减轻它的影响。对于多重共线性的处理方式,有以下几种思路:
(1)提前筛选变量:可以利用相关检验来或变量聚类的方法。注意:决策树和随机森林也可以作为提前筛选变量的方法,但是它们对于多重共线性帮助不大,因为如果按照特征重要性排序,共线性的变量很可能都排在前面。
(2)子集选择:包括逐步回归和最优子集法。因为该方法是贪婪算法,理论上大部分情况有效,实际中需要结合第一种方法。
(3)收缩方法:正则化方法,包括岭回归和LASSO回归。LASSO回归可以实现筛选变量的功能。
(4)维数缩减:包括主成分回归(PCR)和偏最小二乘回归(PLS)方法。
由于篇幅原因,关于这些处理方法,后续会慢慢介绍。
▌强影响点分析
强影响点指的就是离散点。这个很容易联想到,如果有一些离散点远离大部分数据,那么拟合出来的模型可能就会偏离正常轨迹,受到影响。因此,在做线性回归诊断分析的时候也必须把这些强影响点考虑进去,进行分析。针对于强影响点分析,一般的有以下几种方法:
(1)学生化残差
(2)Cook's D统计量
(3)DFFITS统计量
(4)DFBETAS统计量
1. 学生化残差(SR)
学生化残差(SR)指残差标准化后的数值。一般的当样本量为几百时,学生化残差大于2的点被视为强影响点,而当样本量为上千时,学生化残差中大于3的点为相对大的影响点。
2. Cook's D统计量
Cook‘s D统计量用于测量当第i个观测值从分析中去除时,参数估计的改变程度。一般的Cook's D值越大说明越可能是离散点,没有很明确的临界值。建议的影响临界点是:Cook's D > 4/n,即高于此值可被视为强影响点。
3. DFFITS统计量
用于测量第i个观测值对预测值的影响。建议的临界值为:
4. DFBETAS统计量
用于测量当去除第i个观测量时,第j个参数估计的变化程度。建议的影响临界值为:
对于这些指标我们可以通过statsmodels直接查找到,对于我们建立的模型model自动检测每个样本的指标值是多少,我们只需要设置相应的临界点来判断就可以完成检测了。以下是代码实现部分:
# 强离散点各个指标
from statsmodels.stats.outliers_influence import OLSInfluence
import statsmodels.api as sm
model = sm.OLS(yArr,xArr).fit()
OLSInfluence(model).summary_frame().head()
当然,如果我们想单独获取某个指标,我们也可以这样操作:
# 单独获取各个指标
ol = model.get_influence()
leverage = ol.hat_diag_factor
dffits = ol.dffits
resid_stu = ol.resid_studentized_external
cook = ol.cooks_distance
▌线性回归总结
结合前两篇文章对整个线性回归流程做一个总结,可以参照下方流程来进行理解。
以上就是线性回归建模的整个过程,其中还有很多细节没有涉及到,会在后续进行整理并分享,完整代码在知识星球中(点击下方阅读原文)。
参考:
统计学,贾俊平
计量经济学导论,伍德里奇
从零开始学Python数据分析与挖掘,刘顺祥
Python数据科学技术详解与商业实践,常国珍
Python数据科学【读者福利】 ↓↓↓